import { bench, group, run, summary } from "mitata";
import {
  type DecodeAbiParametersReturnType,
  decodeAbiParameters as decodeAbiParametersViem,
  parseAbiParameters,
} from "viem";
import {
  decodeAbiParameter,
  decodeAbiParameters,
} from "./decodeAbiParameters.js";

// TODO(kyle) use generated values to disable jit

group("decodeAbiParameters [uint]", () => {
  summary(() => {
    const abi = [{ type: "uint" }] as const;
    const data =
      "0x0000000000000000000000000000000000000000000000000000000000010f2c";

    bench("viem", () => {
      decodeAbiParametersViem(abi, data);
    }).gc("inner");

    // 66.38 ns/iter
    bench("ponder", () => {
      decodeAbiParameter(abi[0], data);
    }).gc("inner");
  });
});

group("decodeAbiParameters large static", () => {
  summary(() => {
    const abi = parseAbiParameters(
      "((uint256 x,bool y,address z) foo,(uint256 x,bool y,address z) baz,uint8[2] x)",
    );
    const data =
      "0x00000000000000000000000000000000000000000000000000000000000001a40000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a5cc3c03994db5b0d9a5eedd10cabab0813678ac00000000000000000000000000000000000000000000000000000000000000450000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c961145a54c96e3ae9baa048c4f4d6b04c13916b00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002";
    const out = [] as unknown as DecodeAbiParametersReturnType<typeof abi>;

    bench("viem", () => {
      decodeAbiParametersViem(abi, data);
    }).gc("inner");

    // 1.59 µs/iter
    bench("ponder", () => {
      decodeAbiParameters(abi, data, { out });
      // @ts-expect-error
      out.length = 0;
    }).gc("inner");
  });
});

group("decodeAbiParameters large dynamic", () => {
  summary(() => {
    const abi = parseAbiParameters(
      "((uint256[] x,bool y,string[] z) foo,uint256 a,string[] b)",
    );
    const data =
      "0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000001a4000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000568656c6c6f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005776f726c6400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000057761676d6900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000047669656d00000000000000000000000000000000000000000000000000000000";
    const out = [] as unknown as DecodeAbiParametersReturnType<typeof abi>;

    bench("viem", () => {
      decodeAbiParametersViem(abi, data);
    }).gc("inner");

    // 4.17 µs/iter
    bench("ponder", () => {
      decodeAbiParameters(abi, data, { out });
      // @ts-expect-error
      out.length = 0;
    }).gc("inner");
  });
});

run();
